<?php

class WebSignatureMatcher {
	private static $callables = array();
	private static function callableForMatcher($c) {
		if (is_object($c)) {
			if ($c instanceof IWebSignatureHandler)
				$c = array($c, 'matchesSignature');
			else
				throw new CIllegalArgumentException($c, 'c', "not a callable or IWebSignatureHandler.");
		}
		return $c;
	}
	public static function register($c) {
		self::$callables[] = self::callableForMatcher($c);
	}
	
	private static $validators = array();
	public static function registerValidator($v) {
		self::$validators[] = self::callableForMatcher($v);
	}
	
	public static function allMatcherCallables() {
		return self::$callables;
	}
	
	public static function allValidatorCallables() {
		return self::$validators;
	}
	
	public function __construct($matchers = null, $validators = null) {
		CDefault($matchers, self::allMatcherCallables());
		CDefault($validators, self::allValidatorCallables());
		$this->ownCallables = $matchers;
		$this->ownValidators = $validators;
	}
	
	private $ownCallables;
	public function addMatcher($c) {
		$this->ownCallables[] = self::callableForMatcher($c);
	}
	
	public function matcherCallables() {
		return $this->ownCallables;
	}
	
	private $ownValidators;
	public function addValidator($v) {
		$this->ownValidators = self::callableForMatcher($v);
	}
	
	public function validatorCallables() {
		return $this->ownValidators;
	}
	
	public function signatureMatches(IWebRequest $request, $signature, &$captures) {
		if (sizeof($this->ownCallables) == 0 && sizeof($this->ownValidators) == 0)
			return false;
		$signature = WebCompiledSignatureFromPartial($signature);
		$captures = array();
		
		foreach ($this->matcherCallables() as $call) {
			if (!call_user_func_array($call, array($request, $signature, &$captures)))
				return false;
		}
		
		foreach ($this->validatorCallables() as $call) {
			if (!call_user_func_array($call, array($request, $signature, &$captures)))
				return false;
		}
		
		return true;
	}
}

?>